<?php

namespace App\Http\Middleware\BackHome;

use App\Facades\ScarecrowAuth;
use App\Models\BackHome\AuthManage\LoginModel;
use Closure;
use Illuminate\Support\Facades\Crypt;

/**
 * 用户鉴权中间件
 * Class ApiTokenCheckMiddleware
 * @package App\Http\Middleware
 */
class ApiTokenCheckMiddleware
{
    /**
     *  Handle an incoming request.
     * @param $request 请求Request对象
     * @param Closure $next
     * @return mixed
     * @throws \Exception
     */
	public function handle($request, Closure $next)
	{
        // 定义来源
        defined('APP_USER_TOKEN_SRC') or define('APP_USER_TOKEN_SRC', 1);

		$tokenStr = $request->header('SC-API-TOKEN');
		if (!$request->header('SC-API-TOKEN')) {
			$tokenStr = $request->input('SC-API-TOKEN', "");
			if (!$tokenStr) {
				$this->returnError();
			}
		}

		try {
			$token = Crypt::decryptString($tokenStr);
			$userObj = ScarecrowAuth::user($token);
			if (!$userObj) {
				$this->returnError('用户尚未登录');
			}
			//如果是超级管理员则不检测权限
			if ($userObj['is_supper_admin'] != 1) {
				//检查用户权限
				$authList = $userObj['authList'] ?: [];
				if (!$this->CheckAuthList($authList)) {
					$this->returnError('无权限访问此接口');
				}
			}

			//更新TOKEN访问信息
			$info = $this->updateTokenInfo($token, $userObj['tokenInfo']);
			if ($info['code'] !== RETURN_SUCCESS) {
				$this->returnError($info['msg'] . 'TOKEN:' . $token, RETURN_CHECK_TOKEN_FAIL);
			}

			defined('APP_USER_TOKEN') or define('APP_USER_TOKEN', $token);

			return $next($request);
		} catch (\Throwable $e) {
			if (config('app.debug')) {
				$this->returnError($e->getMessage());
			} else {
				$this->returnError();
			}
		}
	}

    /**
     * 检查权限列表
     * @param array $authList
     * @return bool
     */
	public function CheckAuthList($authList = [])
	{
		//在此处填写权限判定逻辑

		//		$nowRoute = strtolower(request()->path());
		//
		//		if (in_array($nowRoute, $authList ? : [])) {
		//			return true;
		//		} else {
		//			return false;
		//		}
		return true;
	}

    /**
     * 更新用户TOKEN信息
     * @param $token 用户TOKEN
     * @param array $tokenInfo 更新的TOKEN_INFO
     * @return array
     * @throws \Exception
     */
	public function updateTokenInfo($token, $tokenInfo = [])
	{
		if ($tokenInfo['is_invalid'] == 1 || $tokenInfo['expire_time'] < time() || $tokenInfo['call_num'] < 1) {
			LoginModel::LoginOut($token);
			return ModelReturn(RETURN_CHECK_TOKEN_FAIL, 'TOKEN已失效，请重新登录');
		}

		$tokenInfo['call_num'] = $tokenInfo['call_num'] - 1;
		$updateCacheData = [
			'call_num'  =>  $tokenInfo['call_num'],
			'update_time'	=>	time()
		];
		return LoginModel::updateTokenCache($token, $updateCacheData, $tokenInfo['call_num'] % 10 === 0);
	}

    /**
     * 返回错误信息
     * @param string $str 错误字符串
     * @param int $code 错误码
     * @throws \Exception
     */
	protected function returnError($str = 'TOKEN错误', $code = RETURN_CHECK_TOKEN_FAIL)
	{
		die(ApiReturn($code, $str));
	}
}
